package com.syt.service.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.syt.service.pojo.PhoneUser;
import com.syt.service.service.PhoneUserService;
import com.syt.service.service.TokenService;
import org.apache.ibatis.plugin.Intercepts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Map;

/**
 * @author syt
 * 登录拦截器
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    PhoneUserService userService;
    @Autowired
    TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // ①:START 方法注解级拦截器
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        // 判断接口是否需要登录
        LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);
        /**
         *         从请求头中 取出 token
         */
        String token = request.getHeader("token");
        /**
         * 浏览器header带不了token，所以用param来带token
         */
        if (token == null || token.equals("")) {
            token = request.getParameter("token");
        }
        // 有 @LoginRequired 注解，需要认证
        if (methodAnnotation != null) {
            if (token == null || token.equals("")) {
                throw new RuntimeException("无token， 请重新登录");
            }
            String userId;
            try {
                userId= JWT.decode(token).getAudience().get(0);
            } catch (JWTDecodeException j) {
                throw new RuntimeException("401, 没有这个 token : " + token);
            }
            if (!tokenService.judgToken(token)) {
                throw new RuntimeException("用户已经过期，请重新登录");
            }
            PhoneUser user = userService.findUserById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在，请重新测试");
            }
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getUserPassword())).build();
            try {
                jwtVerifier.verify(token);
            } catch (JWTVerificationException e) {
                throw new RuntimeException("401, token密码错误");
            }
            request.setAttribute("userId", userId);
            return true;
        }
        return true;
    }

}
